﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using MapLibrary.DataLoading;
using FarseerPhysics.Common.ConvexHull;
using FarseerPhysics.Collision.Shapes;
using FarseerPhysics;
using FarseerPhysics.Common.Decomposition;
using FarseerPhysics.Common;
using MapLibrary.Players;
using AI;
using Enemies;
using MapLibrary;
using MapLibrary.Enemies;

namespace Animation
{
    /// <summary>
    /// This is a factory class that produces Sprites.  It handles all physics
    /// registration duties.
    /// </summary>
    public static class SpriteFactory
    {

        private static ContentManager Content;
        private static SpriteType playerType;

        /// <summary>
        /// Initialize the ContentManager for the factory.
        /// </summary>
        /// <param name="manager"></param>
        public static void Init(ContentManager manager)
        {
            Content = manager;

            playerType = Content.Load<SpriteType>(@"Animation/SpriteTypes/Nanobot");
        }

        public static Sprite CreateSprite(
            GameWorld world,
            SpriteData data)
        {
            return CreateSprite(
                world,
                data.SpriteType,
                data.Position,
                data.Rotation,
                data.Scale,
                data.Collidable);
        }

        //testing

        public static Sprite CreateSprite(
            GameWorld world,
            SpriteType type,
            Vector2 Position)
        {
            return CreateSprite(world, type, Position, 0.0f, new Vector2(1.0f, 1.0f), true);
        }

        public static Sprite CreateSprite(GameWorld world, SpriteType type)
        {
            return CreateSprite(world, type, Vector2.Zero, 0.0f, new Vector2(1.0f, 1.0f), true);
        }

        public static Sprite CreateSprite(
            GameWorld world,
            SpriteType type,
            Vector2 Position,
            float Rotation,
            Vector2 Scale,
            bool Collidable)
        {
            Sprite temp = TranslateType(type);

            temp.Type = type.Clone();
            temp.RegisterToWorld(world);

            temp.Position = Position;
            //((PolygonShape)(temp.Body.FixtureList[0].Shape)).Vertices.Translate(-ConvertUnits.ToSimUnits(temp.GetCenter()));
            temp.SpriteTypeName = type.Name;
            temp.Rotation = Rotation;
            temp.Scale = Scale;

            temp.Type.CurrentState = type.StateList.ElementAt(0).StateName;

            if (type.Name.Equals("Malaria"))
            {
                temp.Body.IgnoreGravity = true;
            }


            Bot b = BotFactory.CreateBot(type.BotName);
            if (b != null)
            {
                b.Owner = temp;
                temp.Bot = b;
            }

            //need to update animation once to set CurrentTexture to something
            temp.Update();

            return temp;
        }

        public static Sprite CreatePlayer(GameWorld world, PlayerData pData, Vector2 Position)
        {
            Player temp = new Player(world);

            temp.Type = playerType.Clone();
            temp.RegisterToWorld(world);

            temp.Position = Position;
            //((PolygonShape)(temp.Body.FixtureList[0].Shape)).Vertices.Translate(-ConvertUnits.ToSimUnits(temp.GetCenter()));
            temp.SpriteTypeName = temp.Type.Name;
            temp.Rotation = 0.0f;
            temp.Scale = Vector2.UnitX + Vector2.UnitY;
            temp.Body.UserData = temp;

            temp.Type.CurrentState = temp.Type.StateList.ElementAt(0).StateName;

            //need to update animation once to set CurrentTexture to something
            temp.Update();

            temp.LoadFromData(pData);

            return temp;
        }

        /// <summary>
        /// Creates the correct sprite class for a given sprite type
        /// </summary>
        public static Sprite TranslateType(SpriteType type)
        {
            string name = type.Name;

            switch (name)
            {
                case "Tuberculosis":
                    return new Tuberculosis();
                case "Alien":
                    return new Sprite();
                case "HIV":
                    return new HIV();
                case "Malaria":
                    return new Malaria();
                case "TuberculosisSpit":
                    return new TuberculosisSpit();
                case "Bullet":
                    return new Bullet();
                case "Germ":
                    return new Germ();
                case "Plank":
                case "Box":
                    return new HookableObject();
                case "ExplodeBox":
                    return new ExplodeableObject();
                case "Chest":
                    return new Chest();
                default:
                    return new Sprite();
            }
        }
    }
}
